home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / pcc12c.zip / ISETUP.A < prev    next >
Text File  |  1989-06-21  |  7KB  |  354 lines

  1. ;    ISETUP.A - Setup for C program execution on IBM PC.
  2.  
  3. ;    jumped to by first instruction to do C initilization.
  4. ;    DS:0 is program segment prefix.
  5. ;    SS is program DS.
  6. ;    SS:0 is size of C initilized memory.
  7. ;    SS:2 is size of uninitilized memory.
  8.  
  9. ;    EQUs define fields.
  10.  
  11. IBM        EQU    21H    ;IBM DOS INTERRUPT NUMBER
  12. CI_CODE        EQU    1
  13. CO_CODE        EQU    2
  14. DIRECT_CODE    EQU    6
  15. DIRECT_INPUT    EQU    7
  16. VERSION        EQU    30H
  17. READ        EQU    3FH
  18. SETBLK        EQU    4AH
  19. TERMINATE    EQU    4CH
  20.  
  21. BS        EQU    8
  22. TAB        EQU    9
  23. LF        EQU    0AH
  24. CR        EQU    0DH
  25. CONTS        EQU    19
  26. CONTX        EQU    24
  27.  
  28.     DSEG
  29.     PUBLIC    _PCB_,_MSDOS2_    ;USED BY CHAIN
  30. NE_MSG    DB    'not enough memory',10
  31. MEMFROM    DW    0        ;FIRSE FREE BYTE IN DS
  32. _PCB_    DW    0        ;_PCB_ SEGMENT REGISTER
  33. _ORIGSP_ DW    0        ;STARTING SP. CAUTION: MUST FOLLOW
  34.                 ;_PCB_
  35. _MSDOS2_ DB    0        ;1 IF VERSION 2.0 OR ABOVE
  36. LASTCH    DB    0
  37. CURCH    DB    0
  38.     PUBLIC    ERRNO_
  39. ERRNO_    RW    1        ;ERROR NUMBER
  40.  
  41.     CSEG
  42.  
  43.     PUBLIC    _CSETUP,EXIT_,PUTCHAR_,GETCHAR_,PUTS_,MAIN_
  44.  
  45. ;    this is the actual entry point for a C88 program.
  46. ;    the following initilization must take place before a program
  47. ;    is actually called.
  48.  
  49. ;    1)    set SP to highest available byte.
  50. ;    2)    set uninitilized storage to zero.
  51. ;    3)    calculate argc and argv.
  52. ;    4)    set DS to users data area.
  53. ;    5)    call main(argc,argv).
  54.  
  55. ;    if program returns then goto exit.
  56.  
  57.  
  58. ;    SET  SP.
  59.  
  60. _CSETUP:
  61.     MOV    SS:_PCB_,DS    ;SAVE _PCB_ FOR EXIT CALL
  62.     MOV    AX,[2]        ;IBM PUTS TOTAL SYSTEM PARAGRAPHS HERE
  63.     MOV    BX,SS        ;CURRENT SS:SP MUST BE WITHIN AVAILABLE
  64.     SUB    AX,BX        ;PARAGRAPHS AVAILABLE FOR DATA
  65.     JBE    NOT_ENOUGH
  66.     DEC    AX        ;PLAY IT SAFE
  67.     CMP    AX,1000H    ;IF OVER 64K THEN SET SP TO 64K
  68.     JC    UNDER_64
  69.     MOV    AX,0FFFH    ;MAXIMUM STACK WITHOUT WRAP
  70. UNDER_64:
  71.     MOV    CL,4        ;TURN PARAGRAPH INTO BYTE
  72.     SHL    AX,CL
  73.     CMP    AX,SP        ;SEE IF BIG ENOUGH
  74.     JC    NOT_ENOUGH
  75.     MOV    BX,SS:[0]    ;IF SP IS INIT DATA+RESDATA+127 THEN MAKE MAX.
  76.     ADD    BX,SS:[2]
  77.     ADD    BX,127
  78.     CMP    SP,BX        ;WANT MAXIMUM ?
  79.     JNZ    HAVE_SP        ;NO, MUST HAVE HAS A -Snn OPTION OF BIND
  80.     MOV    SP,AX        ;HAVE A GOOD STACK
  81. HAVE_SP:MOV    SS:_ORIGSP_,SP    ;REMEMBER STACK FOR EXEC
  82.  
  83.  
  84. ;    REMEMBER VERSION NUMBER
  85.  
  86.     MOV    AH,VERSION    ;CODE TO ASK FOR VERSION
  87.     INT    IBM
  88.     CMP    AL,2        ;IS IT 2 OR ABOVE ?
  89.     JB    OLDVER
  90.     MOV    SS:_MSDOS2_,1    ;TRUE IF VERSION 2 OR ABOVE
  91. OLDVER:
  92.  
  93. ;    CALCULATE ARGC AND ARGV. THE COMMAND TAIL IS BETWEEN 129 AND
  94. ;    255. COMMNAD TAIL IN COPIED TO TOP OF STACK AND ARGV VECTOR
  95. ;    IS PLACED UNDER IT. THE COMMAND NAME IS LAMENTABLY NULL.
  96.  
  97.     MOV    BYTE [255],CR    ;DONT FALL OFF END IF INVALID
  98.     MOV    BYTE [128],' '    ;DONT FALL OFF START EITHER (REPLACES LENGTH)
  99.     MOV    CX,1        ;NUMBER OF ARGUMENTS. ALWAYS (NULL) COMMAND
  100.     MOV    SI,-1        ;LENGTH OF ARGUMENTS.
  101. ;    FIND SIZE OF TAIL
  102. CMD_COUNT:
  103.     INC    SI
  104.     MOV    AL,[SI+129]    ;NEXT COMMAND CHAR
  105.     CMP    AL,CR        ;CR OR LF IS END OF LINE
  106.     JZ    END_COUNT
  107.     CMP    AL,LF
  108.     JNZ    CMD_COUNT
  109. END_COUNT:
  110.     MOV    AX,0        ;NEED ZERO AT END
  111.     PUSH    AX
  112.     TEST    SI,1        ;NEED WORD ALLIGNED STACK
  113.     JZ    WORD_A
  114.     INC    SP        ;ODD NOW SO EVEN LATER
  115. WORD_A:    MOV    DI,SP        ;REMEMBER LOC OF ZERO
  116.     SUB    SP,SI        ;MAKE ROOM FOR TAIL
  117.     MOV    BP,SP        ;BP CAN ADDRESS NEW TAIL
  118. NTAIL:    DEC    SI
  119.     CMP    SI,-1        ;-1 WHEN DONE
  120.     JZ    SAVE_ARGS
  121. ;    A NON WHITE SPACE PRECEEDED BY WHITE MEANS ANOTHER ARGUMENT
  122.     MOV    AL,[SI+129]
  123.     CMP    AL,' '        ;SEE IF WHITE
  124.     JZ    WHITE
  125.     CMP    AL,TAB
  126.     JNZ    NOT_WHITE
  127. WHITE:    MOV    AL,0        ;SET WHITE TO NULL FOR END OF STRING
  128.     JMP    STUFF
  129.  
  130. ;    IS PRECEEDING A WHITE?
  131. NOT_WHITE:
  132.     CMP    BYTE [SI+128],' '
  133.     JZ    NEW_ARG
  134.     CMP    BYTE [SI+128],TAB
  135.     JNZ    STUFF
  136. NEW_ARG:LEA    BX,[BP+SI]    ;STORE ARGV ELEMENT
  137.     PUSH    BX
  138.     INC    CX        ;INCREMENT ARGC
  139. STUFF:    MOV    [BP+SI],AL    ;PUT TAIL CHAR ON STACK
  140.     JMP    NTAIL
  141.  
  142. ;    SAVE A POINTER TO A ZERO FOR ARGV[0]
  143. SAVE_ARGS:
  144.     PUSH    DI
  145.  
  146. ;    SAVE    ARGV AND ARGC
  147.     MOV    BP,SP        ;DONT PUSH SP AS 286 IS DIFFERENT
  148.     PUSH    BP        ;*ARGV[]
  149.     PUSH    CX        ;ARGC
  150.  
  151. ;    SET DS TO CORRECT VALUE
  152.  
  153.     MOV    AX,SS
  154.     MOV    DS,AX
  155.  
  156. ;    INITILIZE UNINITILIZED MEMORY TO ZERO
  157.  
  158.     MOV    DI,[0]        ;LENGTH OF INITILIZED MEMORY IS HERE
  159.     MOV    CX,[2]        ;LENGTH OF UNINITILIZED IS HERE
  160.     MOV    ES,AX        ;ES=DS
  161.     MOV    AL,0        ;THE ZERO
  162.     CLD
  163. REP    STOSB
  164.  
  165. ;    REMEMBER LOW ADDRESS OF FREE MEMORY
  166.  
  167.     ADD    DI,2        ;MAKE WORD ALLIGNED
  168.     AND    DI,0FFFEH
  169.     MOV    MEMFROM,DI    ;PUT AWAY FOR MEMORY CALL
  170.  
  171. ;    NOW READY FOR MAIN
  172.  
  173.     CALL    MAIN_        ;AND DO THE PROGRAM
  174.  
  175. ;    FALL INTO EXIT IF RETURN
  176.  
  177.     MOV    AL,0        ;SET RETURN CODE TO ZERO
  178.     JMP    DOEXIT
  179.  
  180. ;    exit();
  181.  
  182. EXIT_:    POP    AX        ;RETRIEVE RETURN CODE
  183.     POP    AX
  184. DOEXIT:                ;IN DOS 2.0 USE CODE 4C TO TERMINATE
  185.                 ;AS THIS ALLOWS AN ERROR CODE
  186.     CMP    _MSDOS2_,0    ;DOS 1.0 ?
  187.     JZ    OLDEND
  188.     MOV    AH,TERMINATE    ;DOC 2.0 TERMINATE CODE
  189.     INT    IBM
  190.  
  191.  
  192. OLDEND:    PUSH    _PCB_        ;CREATE A LONG RETURN TO _PCB_:0
  193.     MOV    AX,0
  194.     PUSH    AX
  195.     LRET
  196.  
  197. NOT_ENOUGH:
  198.     MOV    AX,&NE_MSG
  199.     PUSH    AX
  200.     CALL    PUTS_
  201.     ADD    SP,2
  202.     MOV    AL,2        ;ERROR EXIT
  203.     JMP    DOEXIT
  204.  
  205.  
  206. ;    charactor = getchar();
  207.  
  208. GETCHAR_:
  209.     CMP    LASTCH,0    ;SAVED CHAR
  210.     JZ    DOGC
  211. GLAST:    MOV    AL,LASTCH    ;RETURN LAST CHAR
  212.     MOV    LASTCH,0
  213.     JMP    GOTIN
  214. DOGC:    MOV    AH,CI_CODE    ;CODE FOR ECHOED INPUT
  215.     INT    IBM        ;DO THE CONSOLE READ
  216. GOTIN:    MOV    AH,0        ;RETURN A WORD
  217.     CMP    AL,26        ;CONTROL z ?
  218.     JZ    READNFG
  219.     RET            ;CHARACTER IS IN AL
  220. READNFG:MOV    AX,-1        ;-1 IF EOF
  221.     RET
  222.  
  223.  
  224. ;    putchar(character);
  225.  
  226. PUTCHAR_:POP    AX        ;RETURN ADDRESS
  227.     POP    DX        ;DL IS CHARACTER
  228.     PUSH    DX
  229.     PUSH    AX
  230.     CMP    DL,LF        ;MUST CHANGE LF TO CR,LF
  231.     JNZ    XCO
  232.     MOV    DL,CR        ;PRINT THE CR FIRST
  233.     CALL    XCO
  234.     MOV    DL,LF        ;PUT THE LF BACK
  235. XCO:    MOV    AH,CO_CODE
  236.     INT    IBM        ;DO THE WRITE
  237.     RET
  238.  
  239.  
  240. ;    puts(string address);
  241.  
  242. PUTS_:    POP    AX        ;RETURN ADDRESS
  243.     POP    BX        ;STRING ADDRESS
  244.     PUSH    BX
  245.     PUSH    AX
  246. PS_LP:    MOV    AL,[BX]        ;NEXT CHAR
  247.     OR    AL,AL
  248.     JZ    PS_END        ;ZERO AT END OF STRING
  249.     PUSH    BX
  250.     PUSH    AX        ;CHAR
  251.     CALL    PUTCHAR_    ;LET PUTCHAR TURN LF INTO CR,LF
  252.     ADD    SP,2
  253.     POP    BX
  254.     INC    BX        ;STRING POINTER
  255.     JMP    PS_LP
  256. PS_END:    RET
  257.  
  258.  
  259.  
  260.  
  261.     PUBLIC    CI_, CO_, CSTS_
  262.  
  263. ;    charactor = ci();
  264.  
  265. CI_:    CMP    LASTCH,0    ;SAVED CHAR
  266.     JZ    DOCI
  267.     MOV    AL,LASTCH    ;RETURN LAST CHAR
  268.     MOV    LASTCH,0
  269.     MOV    AH,0
  270.     RET
  271. DOCI:    MOV    AH,DIRECT_INPUT    ;CODE FOR DIRECT CONSOLE INPUT
  272.     INT    IBM
  273.     MOV    AH,0        ;MAKE AN INT
  274.     RET
  275.  
  276.  
  277. ;    charactor or zero = csts();
  278.  
  279. CSTS_:    MOV    AH,DIRECT_CODE    ;CODE FOR DIRECT CONSOLE IO
  280.     MOV    DL,0FFH        ;WANT A CHAR
  281.     INT    IBM
  282.     MOV    LASTCH,AL    ;SAVE CHARACTER
  283.     MOV    AH,0        ;MAKE AN INT
  284.     RET
  285.  
  286.  
  287. ;    co(character);
  288.  
  289. CO_:    POP    AX        ;RETURN ADDRESS
  290.     POP    DX
  291.     PUSH    DX
  292.     PUSH    AX
  293.     MOV    AH,DIRECT_CODE    ;WANT A DIRECT CONSOLE OUTPUT
  294.     INT    IBM
  295.     RET
  296.  
  297.  
  298.  
  299.  
  300. ;    MEMORY MANAGEMENT FUNCTIONS: _MEMORY, _SHOWSP, _SETSP
  301.  
  302.     PUBLIC    _MEMORY_,_SETSP_,_SHOWSP_
  303.  
  304. _MEMORY_:MOV    AX,MEMFROM    ;ADDRESS OF FIRST FREE BYTE OF MEMORY
  305.     RET
  306.  
  307. _SHOWSP_:POP    DX        ;RETURN ADDRESS
  308.     MOV    AX,SP        ;RETURN SP VALUE TO USER
  309.     JMP    DX
  310.  
  311. _SETSP_:
  312.     POP    DX        ;CHOP THE STACK - DANGEROUS OPERATION
  313.     POP    BX        ;NEW SP VALUE
  314.     CMP    BP,SP        ;ANY LOCALS
  315.     JNZ    NOC
  316.     MOV    BP,BX        ;MUST MOVE THE BP TOO
  317. NOC:    MOV    SP,BX
  318.     PUSH    BX
  319.     JMP    DX
  320.  
  321.  
  322. ;    SEGMENT REGISTER FUNCTIONS: _SHOWDS, _SHOWCS, _SETDS
  323.  
  324.     PUBLIC    _SHOWDS_,_SHOWCS_,_SETDS_
  325.  
  326. _SHOWDS_:MOV    AX,DS        ;DS (AND SS) VALUE
  327.     RET
  328.  
  329. _SHOWCS_:MOV    AX,CS        ;CS VALUE
  330.     RET
  331.  
  332. _SETDS_:POP    DX        ;RETURN VALUE
  333.     POP    DS        ;NEW DS
  334.     PUSH    DS
  335.     JMP    DX        ;RETURN
  336.  
  337.  
  338.  
  339.  
  340. ;    OS CALL USED BY OPEN, CREAT ETC.
  341.  
  342. ;    VALUE=_OS(CODE,ARGUMENT);
  343.  
  344.     PUBLIC    _OS_
  345. _OS_:    PUSH    BP
  346.     MOV    BP,SP
  347.     MOV    AH,[BP+4]    ;IBM CODE
  348.     MOV    DX,[BP+6]    ;ARGUMENT POINTER
  349.     INT    IBM
  350.     MOV    AH,0        ;MAKE RETURN AN INTEGER
  351.     POP    BP
  352.     RET
  353.  
  354.